import styleVar from '@/styles/variable.module.scss'
import { ref } from 'vue'

const storeKey = 'PROJECT_THEME'
const themeList = styleVar.themes.split(', ')
type ThemeItem = typeof themeList[number]

export class Theme {
  static get themeList() {
    return themeList
  }
  static #theme = ref(uni.getStorageSync<ThemeItem>(storeKey) || Theme.themeList[0])
  static get theme() {
    return this.#theme.value
  }

  static setTheme(theme: ThemeItem) {
    if (!this.themeList.includes(theme) || this.theme === theme) return
    uni.setStorageSync(storeKey, theme)
    this.#theme.value = theme
  }

  /**
   * 提取渐变色
   */
  static parseGradientString(gradient: string) {
    // 提取函数名
    const funcNameMatch = gradient.match(/^([a-z-]+)\(/i)
    const funName = funcNameMatch ? funcNameMatch[1] : ''

    // 提取括号内的参数
    const paramStart = gradient.indexOf('(')
    const paramEnd = gradient.lastIndexOf(')')
    const paramStr = gradient.slice(paramStart + 1, paramEnd)

    // 分割参数，处理逗号分隔且忽略括号内的逗号
    const params: string[] = []
    let currentParam = ''
    let parenCount = 0
    for (let i = 0; i < paramStr.length; i++) {
      const char = paramStr[i];
      if (char === '(') {
        parenCount++
      } else if (char === ')') {
        parenCount--
      }
      if (char === ',' && parenCount === 0) {
        params.push(currentParam.trim())
        currentParam = ''
      } else {
        currentParam += char
      }
    }
    params.push(currentParam.trim())

    // 处理角度和颜色
    const angleRules: Record<string, { regexp: RegExp; default: string }> = {
      'linear-gradient': {
        regexp: /^(to\s+(top|bottom|left|right)(\s+(top|bottom|left|right))?|\d+deg)/,
        default: '180deg'
      },
      'radial-gradient': {
        regexp: /^(circle|ellipse)(?:\s+(closest-side|farthest-side|closest-corner|farthest-corner|contain|cover))?(?:\s+at\s+[\w\s%]+)?/,
        default: 'ellipse at center'
      },
      'conic-gradient': {
        regexp: /^(from\s+\d+deg)(?:\s+at\s+[\w\s%]+)?|(at\s+[\w\s%]+)/,
        default: 'from 0deg at center'
      },
      'repeating-linear-gradient': {
        regexp: /^(to\s+(top|bottom|left|right)(\s+(top|bottom|left|right))?|\d+deg)/,
        default: '180deg'
      },
      'repeating-radial-gradient': {
        regexp: /^(circle|ellipse)(?:\s+(closest-side|farthest-side|closest-corner|farthest-corner|contain|cover))?(?:\s+at\s+[\w\s%]+)?/,
        default: 'ellipse at center'
      },
      'repeating-conic-gradient': {
        regexp: /^(from\s+\d+deg)(?:\s+at\s+[\w\s%]+)?|(at\s+[\w\s%]+)/,
        default: 'from 0deg at center'
      }
    }

    let angle = angleRules[funName]?.default;
    if (params.length > 0 && angleRules[funName]) {
      const firstParam = params[0]
      const match = firstParam.match(angleRules[funName].regexp)
      if (match) {
        angle = params.shift()!
      }
    }

    // 处理颜色和停靠点
    const colors: { color: string; start?: string; end?: string }[] = []
    const colorRegex = /^(\#[\da-fA-F]{3,8}|rgb\([^)]+\)|rgba\([^)]+\)|hsl\([^)]+\)|hsla\([^)]+\)|[a-z]+)/i
    params.forEach((param) => {
      const colorMatch = param.match(colorRegex)
      if (colorMatch) {
        const color = colorMatch[0]
        const remaining = param.slice(color.length).trim()
        const parts = remaining.split(/\s+/).filter(Boolean)
        const colorInfo: typeof colors[number] = { color }
        if (parts.length === 1) {
          colorInfo.start = parts[0]
        } else if (parts.length === 2) {
          colorInfo.start = parts[0]
          colorInfo.end = parts[1]
        }
        colors.push(colorInfo)
      }
    })

    return { funName, angle, colors }
  }

  /**
   * rgb  - 6位 hex
   * 
   * rgba - 8位 hex
   */
  static rgbToHex(color: string) {
    const isRgba = color.startsWith('rgba')
    const arr = color.replace(/^rgba?\(|\)$/g, '').split(',')
    const opacityLen = 3
    const primaryColors = arr.slice(0, opacityLen)
    const opacity = +(arr[opacityLen] ?? 1) * 255

    return '#' + primaryColors.concat(isRgba ? [opacity + ''] : [])
      .map(item => Number(item).toString(16)).join('')
  }

  /**
   * hex 转 rgba
   * 
   * color 可以传递 #fff、#fff8、#fff222、#fff22288 这四种长度
   */
  static hexToRgba(color: string) {
    const str = color.slice(1)
    let hex = str, opacity = 'ff'

    if (str.length === 3) hex += hex
    if (str.length === 4) {
      const len = str.length - 1
      const a = str.slice(0, len)
      const b = str.slice(len)
      hex = a + a
      opacity = b + b
    }
    if (str.length === 8) {
      const len = str.length - 2
      hex = str.slice(0, len)
      opacity = str.slice(len)
    }

    const primaryColors = hex.match(/.{2}/g)?.map(item => +`0x${item}`)
      .concat([+`0x${opacity}` / 255]).join(', ')

    return `rgba(${primaryColors})`
  }
}